<template>
    <div class="app-container">
        <div class="filter-container">
            <el-select class="filter-item semester-select" v-model="semesterId" placeholder="请选择学期" @change="changeSemester">
                <el-option v-for="(item, index) in semesterData" :key="index" :value="item.id"
                    :label="item.semesterName"></el-option>
            </el-select>
            <el-select class="filter-item class-select" @change="handleSelectChange" @clear="clearListener" clearable
                v-model="classNo" placeholder="请选择班级">
                <el-option v-for="(item, index) in classData" :key="index" :value="item.classNo"
                    :label="item.className"></el-option>
            </el-select>
            <el-button class="filter-item" type="primary" @click="exportExcel">导出课表</el-button>
        </div>
        <br />
        <el-table :data="classTableData.lessons" border style="width: 100%" id="my-table">
            <!-- 时间列 -->
            <el-table-column prop="name" label="时间" width="180">
                <template #default="scope">
                    <p>{{ "第" + digital2Chinese(scope.$index + 1) + "节" }}</p>
                    <p class="period">{{ scope.row }}</p>
                </template>
            </el-table-column>

            <!-- 周次和课程信息列 -->
            <el-table-column v-for="(weekNum, weekIndex) in classTableData.courses" :key="weekIndex"
                :label="'周' + digital2Chinese(weekIndex + 1, 'week')" width="180">
                <template #default="scope">
                    <div class="course-info" v-html="classTableData.courses[weekIndex][scope.$index]"></div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue';
import FileSaver from 'file-saver';
import * as XLSX from 'xlsx'; // 使用 import * as XLSX
import { ElMessage } from 'element-plus';

import axios from 'axios';

const classTimeTableData = ref([]);
const classData = ref([]);
const semesterData = ref([]);
const classNo = ref('');
const semesterId = ref('');
const listLoading = ref(true);

const classTableData = ref({
    lessons: [
        "08.20-09.55",
        "10.15-11.50",
        "14.20-15.55",
        "16.15-17.50",
        "18.30-20.05",
    ],
    courses: [[], [], [], [], [], [], []],
    timetableId: [[], [], [], [], [], [], []], // 添加 timetableId
    timeslot: [[], [], [], [], [], [], []],    // 添加 timeslot
});

const getList = () => {
    listLoading.value = true;
    classTableData.value.courses.forEach(item => {
        item.length = 0;
    });
    axios
        .get("/api/timetable/getList", {
            headers: {
                token: localStorage.getItem("token"),
            },
        })
        .then((res) => {
            let ret = res.data.data;
            classTimeTableData.value = ret.records; // 假设后端返回的数据结构与之前一致
            setToTable(ret);
            listLoading.value = false;
        })
        .catch(() => {
            ElMessage.error("查询课程表失败");
            listLoading.value = false; // 确保在出错时也设置loading为false
        });
};

const getClassNo = () => {
    listLoading.value = true;
    axios
        .get("/api/classes/getList",{
          headers: {
            "token": localStorage.getItem("token"),
          },
        })
        .then((res) => {
            classData.value = res.data.data;
            listLoading.value = false;
        })
        .catch(() => {
            ElMessage.error("查询班级失败");
            listLoading.value = false;
        });
};

const getSemester = () => {
    listLoading.value = true;
    axios
        .get("/api/semester/getList",{
          headers: {
            "token": localStorage.getItem("token"),
          },
        })
        .then((res) => {
            semesterData.value = res.data.data;
            listLoading.value = false;
            semesterId.value = semesterData.value[0].id;
        })
        .catch(() => {
            ElMessage.error("查询学期失败");
            listLoading.value = false;
        });
};

onMounted(() => {
    getList();
    getClassNo();
    getSemester();
    // Vue 2 mounted 逻辑，如果 $store.getters.getSemesterId 仍然适用
    // const id = proxy.$store?.getters?.getSemesterId; // 安全访问
    // if (id) {
    //     semesterId.value = id;
    // }
});

const changeSemester = () => {
    clearListener();
    // 如果学期更改后需要重新获取所有课表，则调用 getList
    // 如果是根据学期和班级查询，则可能不需要立即调用 getList，而是等班级也选定后再调用 queryClass
    // 这里假设更改学期后，如果班级已选，则查询，否则清空课表
    if (classNo.value) {
        queryClass();
    } else {
        initClassTableData(); // 清空课表数据
    }
};

const initClassTableData = () => {
    classTableData.value = {
        lessons: [
            "08.20-09.55",
            "10.15-11.50",
            "14.20-15.55",
            "16.15-17.50",
            "18.30-20.05",
        ],
        courses: [[], [], [], [], [], [], []],
        timetableId: [[], [], [], [], [], [], []],
        timeslot: [[], [], [], [], [], [], []],
    };
    return true;
};

const setToTable = (ret) => {
    if (!initClassTableData()) {
        return;
    }

    let level = 0;
    let index = 0;
    let beforeTimeslot = -1;
    let flag = false; // flag为true表示 全空

    if (classNo.value == "") {
        flag = true;
    }
    if (semesterId.value == null || semesterId.value === '') { // 检查 semesterId 是否为空
        flag = true;
    }

    for (let timess = 0; timess < 35; timess++) {
        const item = ret[index];
        if (!flag && item != undefined && beforeTimeslot == item.timeslot) {
            timess--;
        }
        level = Math.floor(timess / 5);
        if (flag || index >= ret.length || parseInt(item.timeslot) != timess) {
            classTableData.value.courses[level].push("");
            classTableData.value.timetableId[level].push(-1);
            classTableData.value.timeslot[level].push(timess);
        } else {
            let section =
                "(" +
                ((item.timeslot % 5) * 2 + 1) +
                "-" +
                ((item.timeslot % 5) * 2 + 2) +
                "节)";
            let biweekly =
                item.biweekly == 1 ? "(单)" : item.biweekly == 2 ? "(双)" : "";
            let time =
                section + item.startWeek + "-" + item.endWeek + "周" + biweekly;
            let className = item.className;
            let teacherName = item.teacherName;
            let roomName = item.roomName;
            let course = item.courseNo + "-" + item.courseName;
            let size = item.size;

            let msg =
                time +
                "/" +
                className +
                "/" +
                teacherName +
                "/" +
                roomName +
                "/" +
                course +
                "/" +
                "选课人数：" +
                size;

            if (beforeTimeslot != item.timeslot) {
                classTableData.value.courses[level].push(msg);
                // 确保 timetableId 和 timeslot 数组的对应索引存在
                if (!classTableData.value.timetableId[level]) classTableData.value.timetableId[level] = [];
                classTableData.value.timetableId[level][item.timeslot % 5] = item.id;
                classTableData.value.timeslot[level].push(item.timeslot);
            } else {
                let oldmsg = classTableData.value.courses[level][item.timeslot % 5];
                classTableData.value.courses[level][item.timeslot % 5] =
                    oldmsg + "<br/>" + msg;
                let oldid =
                    classTableData.value.timetableId[level][item.timeslot % 5];
                classTableData.value.timetableId[level][item.timeslot % 5] =
                    oldid + "@@@" + item.id;
                // timeslot 也应该对应添加，但原逻辑是 push，可能导致不一致
                // classTableData.value.timeslot[level].push(item.timeslot); // 这行可能需要审视逻辑
            }

            beforeTimeslot = item.timeslot;
            index++; // 只有在成功处理一个 item 后才增加 index
        }
    }

    if (ret.length == 0 && !flag) { // 只有在有班级和学期选择，但返回数据为空时提示
        ElMessage({ message: "暂无课表", type: "success" });
    }
    // console.log(classTableData.value);
};

const queryClass = () => {
    if (!semesterId.value || !classNo.value) {
        ElMessage.warning('请先选择学期和班级');
        initClassTableData(); // 清空课表
        return;
    }
    listLoading.value = true;
    // 清空现有课程数据，但保留 lessons 结构
    classTableData.value.courses = [[], [], [], [], [], [], []];
    classTableData.value.timetableId = [[], [], [], [], [], [], []];
    classTableData.value.timeslot = [[], [], [], [], [], [], []];

    axios
        .get(
            `/api/timetable/class/${semesterId.value}/${classNo.value}`
            ,{
              headers: {
                "token": localStorage.getItem("token"),
              },
            })
        .then((res) => {
            // console.log(res);
            let ret = res.data.data;
            setToTable(ret);
            listLoading.value = false;
        })
        .catch(() => {
            ElMessage.error("查询课表失败");
            listLoading.value = false;
        });
};

const exportExcel = () => {
    const myTableElement = document.getElementById("my-table");
    if (!myTableElement) {
        ElMessage.error("找不到课表元素");
        return;
    }
    const ws = XLSX.utils.table_to_sheet(myTableElement);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Sheet1");

    const defaultColWidth = 20;
    const range = XLSX.utils.decode_range(ws["!ref"]);
    if (!ws["!cols"]) ws["!cols"] = [];
    for (let C = range.s.c; C <= range.e.c; ++C) {
        ws["!cols"][C] = { width: defaultColWidth };
    }

    const defaultRowHeight = 100;
    if (!ws["!rows"]) ws["!rows"] = [];
    ws["!rows"][0] = { hpx: 20 };

    for (
        let R = 1;
        R <= 6 && ws[XLSX.utils.encode_cell({ r: R, c: 0 })];
        ++R
    ) {
        ws["!rows"][R] = { hpx: defaultRowHeight };
    }
    const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" });
    const blob = new Blob([wbout], { type: "application/octet-stream" });
    FileSaver.saveAs(blob, "课表.xlsx");
};

const digital2Chinese = (num, identifier) => {
    const character = [
        "零",
        "一",
        "二",
        "三",
        "四",
        "五",
        "六",
        // "七", // 周日对应 '日'，所以这里可以只到六
    ];
    if (identifier === "week") {
        if (num === 0 || num === 7) return "日"; // 周日
        if (num > 0 && num < 7) return character[num]; // 周一到周六
        return ''; // 其他情况返回空，或根据需要处理
    }
    return character[num] || ''; // 防止 num 超出范围
};

const clearListener = () => {
    classNo.value = '';
    // 清空班级选择后，也应该清空课表数据
    initClassTableData();
};

const handleSelectChange = (val) => {
    classNo.value = val;
    if (val) { // 只有当选择了班级时才查询
        queryClass();
    } else { // 如果清空了班级选择
        initClassTableData();
    }
};


</script>

<style scoped>
.app-container {
    padding: 20px;
}

.filter-container {
    display: flex; /* 使用 flex 布局使子元素在同一行 */
    align-items: center; /* 垂直居中对齐 */
}

.filter-item {
    margin-right: 10px; /* 给每个元素之间添加一些右边距 */
}

.semester-select,
.class-select {
    width: 200px; /* 设置下拉框的宽度，您可以根据需要调整 */
}

/* 如果最后一个元素不需要右边距 */
.filter-item:last-child {
    margin-right: 0;
}

.course-info {
    white-space: pre-wrap;
    /* 保留空白和换行 */
}

/* .class-select 的特定样式如果不再需要，可以移除或注释掉 */
/* .class-select {
    padding-left: 30px;
    padding-right: 30px;
} */
</style>